package moltencore.network.protocol;

import moltencore.game.bubble.Bubble;
import spark.math.Vector2;
import spark.network.Util;

import java.nio.ByteBuffer;
import java.util.LinkedList;

public class RowPushed extends CeilingPushed {
	public static final short TYPE = 0x60;
	private static final byte[] TYPE_BYTES = Util.makeBytes(TYPE);

	private BubbleData[] bubblesData;
	private static final int GRID_BUBBLE_DATA_COUNT_LENGTH = Byte.SIZE / 8;

	protected static final int SIZE =
			CeilingPushed.SIZE +
			GRID_BUBBLE_DATA_COUNT_LENGTH;

	public RowPushed() {
		super(true, TYPE_BYTES);
	}

	public RowPushed(long fieldId, Vector2 direction, LinkedList<Bubble> row) {
		this();
		setFieldId(fieldId);
		setDirection(direction);
		LinkedList<BubbleData> rowBubbles = new LinkedList<BubbleData>();
		for(Bubble bubble : row) {
			rowBubbles.add(new BubbleData(bubble, fieldId));
		}
		this.setBubblesData(rowBubbles.toArray(new BubbleData[rowBubbles.size()]));
	}

	public BubbleData[] getBubblesData() {
		return bubblesData;
	}

	public void setBubblesData(BubbleData[] bubblesData) {
		this.bubblesData = bubblesData;
	}

	@Override
	public void getBytes(byte[] buffer) {
		super.getBytes(buffer);
		ByteBuffer bb = ByteBuffer.wrap(buffer, CeilingPushed.SIZE, buffer.length - CeilingPushed.SIZE);
		bb.put((byte) bubblesData.length);
		for(BubbleData bubbleData : bubblesData) {
			bubbleData.getBytes(bb.array(), bb.position());
			bb.position(bb.position() + BubbleData.SIZE);
		}
	}

	@Override
	public void fill(byte[] buffer) {
		super.fill(buffer);
		ByteBuffer bb = ByteBuffer.wrap(buffer, CeilingPushed.SIZE, buffer.length - CeilingPushed.SIZE);
		bubblesData = new BubbleData[bb.get()];
		for(int i = 0; i < bubblesData.length; i++) {
			bubblesData[i] = new BubbleData();
			bubblesData[i].fill(bb.array(), bb.position());
			bb.position(bb.position() + BubbleData.SIZE);
		}
	}

	@Override
	public int getSize() {
		return SIZE + bubblesData.length * BubbleData.SIZE;
	}

	public static RowPushed create(byte[] buffer, long receiveTime) {
		RowPushed packet = new RowPushed();
		packet.fill(buffer);
		return packet;
	}
}